package com.fcc.wfly.entitlement.service.impl;

import com.fcc.wfly.entitlement.domain.CarePackObligationInfo;
import com.fcc.wfly.entitlement.domain.ObligationClientInfo;
import com.fcc.wfly.entitlement.domain.WarrantyInfo;
import com.hp.it.gssops.Services.ObligationInfoService;
import com.hp.it.gssops.Services.ObligationInfoServiceImpl;
import com.hp.it.gssops.beans.ObligationInfo;
import com.fcc.wfly.entitlement.domain.ContractInfo;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

@Service("obligationService")
public class ObligationServiceImpl implements ObligationService {

	public ObligationClientInfo retrieveActiveOrLatestServiceObligationByProductIdentifier(String serialNumber,
                                                                                           String productID, String shipToCountry, String shipToDate) throws Exception {
		ObligationInfoService obligationInfoService = new ObligationInfoServiceImpl();
		List<ObligationInfo> obligationInfos = obligationInfoService
				.retrieveActiveOrLatestServiceObligationByProductIdentifier(serialNumber, productID, shipToCountry,
						shipToDate);

		return this.getAllActiveOrLatestObligation(obligationInfos);
	}

	private ObligationClientInfo getAllActiveOrLatestObligation(List<ObligationInfo> ois) throws ParseException {
		if (ois == null || ois.size() == 0) {
			System.out.println("Error: No obligation");
			return null;
		}
		ObligationInfo contract = new ObligationInfo();
		List<ObligationInfo> results = new ArrayList<ObligationInfo>();
		ObligationInfo warranty = new ObligationInfo();
		Map<String, ObligationInfo> carepacks = new HashMap<String, ObligationInfo>();
		ObligationClientInfo oci = new ObligationClientInfo();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		for (ObligationInfo oi : ois) {
			// if printer was not entitled, then return the first element of ois
			if (oi.getExistsIndicator().equalsIgnoreCase("FALSE")) {
				oci.setExistsIndicator(oi.getExistsIndicator());
				oci.setErrorMessage(oi.getErrorMessage());
				return oci;
			}

			// if this obligation is C, then check if it's the active or latest
			if (oi.getObligationType().equalsIgnoreCase("C")) {
				// if it's active C, then contract is this obligation
				if (oi.getObligationStatus().equalsIgnoreCase("A")) {
					contract = oi;
				}
				// if contract is not initialized, then contract to be
				// initialized with oi,
				// otherwise compare to start date of oi
				else if (contract.getObligationStartDate() == null || contract.getObligationStartDate().length() == 0) {
					contract = oi;
				}
				// if start date of contract is earlier than start date of oi,
				// the reset contract = oi
				else if (formatter.parse(contract.getObligationStartDate())
						.compareTo(formatter.parse(oi.getObligationStartDate())) < 0) {
					contract = oi;
				}
			}
			// if this obligation is P, then check if it's active or latest
			else if (oi.getObligationType().equalsIgnoreCase("P")) {
				// if it's active P, then put it to carepacks with key "P__" +
				// offercode
				if (oi.getActiveEntitlementIndicator().equalsIgnoreCase("TRUE")) {
					carepacks.put("P__" + oi.getOfferCode(), oi);
				}
				// if this P is not active, then check if it's in carepacks, if
				// yes, then check if its start date is greater than oi's
				// if not, then put it to carepacks
				else if (!carepacks.containsKey("P__" + oi.getOfferCode())) {
					carepacks.put("P__" + oi.getOfferCode(), oi);
				}
				// if oi's start date is greater than the one in carepacks, then
				// replace the older one
				else if (formatter.parse(carepacks.get("P__" + oi.getOfferCode()).getObligationStartDate())
						.compareTo(formatter.parse(oi.getObligationStartDate())) < 0) {
					carepacks.put("P__" + oi.getOfferCode(), oi);
				}
			}
			// if this obligation is W, then check if it's active or latest
			else if (oi.getObligationType().equalsIgnoreCase("W")) {
				// if it's active W, then set warranty = oi
				if (oi.getActiveEntitlementIndicator().equalsIgnoreCase("TRUE")) {
					warranty = oi;
				}
				// if warranty is not initialized, then warranty to be
				// initialized as oi
				// otherwise, compare the start date
				else if (warranty.getObligationStartDate() == null || warranty.getObligationStartDate().length() == 0) {
					warranty = oi;
				}
				// if oi's start date is greater than warranty's, then reset
				// warranty = oi
				else if (formatter.parse(warranty.getObligationStartDate())
						.compareTo(formatter.parse(oi.getObligationStartDate())) < 0) {
					warranty = oi;
				}
			}
		}

		// if no C, then check if existing P and W
		if (contract.getObligationStartDate() == null || contract.getObligationStartDate().length() == 0) {
			// check if exists P, yes, then set contract to a P
			if (!carepacks.isEmpty()) {
				for (Entry<String, ObligationInfo> entry : carepacks.entrySet()) {
					System.out.println(entry.getKey());
					contract = entry.getValue();
					break;
				}
			}
			// check if exists W, yes, the set contract to W
			else if (warranty.getObligationStartDate() != null && warranty.getObligationStartDate().length() > 0) {
				contract = warranty;
			}
		}

		// Initiate oci
		oci.setCi(this.getContractInfo(contract));
		oci.setWi(this.getWarrantyInfo(warranty));
		List<CarePackObligationInfo> cps = new ArrayList<CarePackObligationInfo>();
		for (Entry<String, ObligationInfo> entry : carepacks.entrySet()) {
			cps.add(this.getCarePack(entry.getValue()));
		}
		oci.setCarePackObligationInfo(cps);
		oci.setEntitlementCheckDate(warranty.getEntitlementCheckDate());
		oci.setErrorMessage(warranty.getErrorMessage());
		oci.setExistsIndicator(warranty.getExistsIndicator());
		oci.setProductDescription(warranty.getProductDescription());
		oci.setProductID(warranty.getProductID());
		oci.setSerialNumber(warranty.getSerialNumber());
		oci.setShipToCountry(warranty.getShipToCountry());

		return oci;
	}

	// initiate a warrantyInfo from an ObligationInfo
	private WarrantyInfo getWarrantyInfo(ObligationInfo oi) {
		WarrantyInfo wi = new WarrantyInfo();
		wi.setActive(oi.getActiveEntitlementIndicator());
		wi.setCovWindow(oi.getCovwindow());
		wi.setFactoryWarrantyEndDate(oi.getFactoryWarrantyEndDate());
		wi.setFactoryWarrantyStartDate(oi.getFactoryWarrantyStartDate());
		wi.setFactoryWarrantyTermCode(oi.getFactoryWarrantyTermCode());
		wi.setOfferCode(oi.getOfferCode());
		wi.setOfferDescription(oi.getOfferDescription());
		wi.setOverallWarrantyEndDate(oi.getObligationEndDate());
		wi.setOverallWarrantyStartDate(oi.getObligationStartDate());
		wi.setResponseCommitment(oi.getResponseCommitment());
		wi.setSalesOrderNumber(oi.getSalesOrderNumber());
		wi.setStatus(oi.getObligationStatus());
		wi.setWarrantyDeterminationDescription(oi.getWarrantyDeterminationDescription());
		return wi;
	}

	// Initiate a contractInfo from an ObligationInfo
	private ContractInfo getContractInfo(ObligationInfo oi) {
		ContractInfo ci = new ContractInfo();
		ci.setActive(oi.getActiveEntitlementIndicator());
		if (oi.getObligationType().equalsIgnoreCase("C")) {
			ci.setOfferCode(oi.getOfferCode());
			ci.setOfferDescription(oi.getOfferDescription());
		}
		ci.setOverallContractEndDate(oi.getObligationEndDate());
		ci.setOverallContractStartDate(oi.getObligationStartDate());
		ci.setStatus(oi.getObligationStatus());
		return ci;
	}

	private CarePackObligationInfo getCarePack(ObligationInfo oi) {
		CarePackObligationInfo cp = new CarePackObligationInfo();
		cp.setActive(oi.getActiveEntitlementIndicator());
		cp.setCarePackProductNumber(oi.getCarePackProductNumber());
		cp.setCarepackSerialNumber(oi.getCarepackSerialNumber());
		cp.setCovWindow(oi.getCovwindow());
		cp.setOfferCode(oi.getOfferCode());
		cp.setOfferDescription(oi.getOfferDescription());
		cp.setOverallCarepackEndDate(oi.getObligationEndDate());
		cp.setOverallCarepackStartDate(oi.getObligationStartDate());
		cp.setResponseCommitment(oi.getResponseCommitment());
		cp.setSalesOrderNumber(oi.getSalesOrderNumber());
		cp.setStatus(oi.getObligationStatus());
		return cp;
	}

	// private List<ObligationClientInfo>
	// filterObligationInfo(List<ObligationInfo> obligationInfos)
	// throws ParseException {
	// List<ObligationClientInfo> obligationClientInfoList = new ArrayList<>();
	// ObligationClientInfo clientInfo = new ObligationClientInfo();
	// List<CarePackObligationInfo> carePackObligationInfos = new ArrayList<>();
	// CarePackObligationInfo carePackObligationInfo = new
	// CarePackObligationInfo();
	// if (!obligationInfos.isEmpty()) {
	// SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
	// for (ObligationInfo info : obligationInfos) {
	// if (clientInfo.getProductID() == null) {
	// this.getLatestInfoResult(clientInfo, info);
	// } else {
	// if (info.getObligationType().compareTo(clientInfo.getObligationType()) <
	// 0) {
	// this.getLatestInfoResult(clientInfo, info);
	// } else if
	// (info.getObligationType().compareTo(clientInfo.getObligationType()) > 0)
	// {
	// clientInfo = this.getClientInfoResult(clientInfo);
	// } else {
	// if (clientInfo.getObligationType().equalsIgnoreCase("C")
	// || info.getObligationType().equalsIgnoreCase("C")) {
	// if (info.getObligationStatus().equalsIgnoreCase("A")) {
	// this.getLatestInfoResult(clientInfo, info);
	// } else if (clientInfo.getObligationStatus().equalsIgnoreCase("A")) {
	// clientInfo = this.getClientInfoResult(clientInfo);
	// } else {
	// if (info.getObligationStartDate() != null
	// && clientInfo.getOverallContractStartDate() != null) {
	// if (formatter.parse(info.getObligationStartDate())
	// .compareTo(formatter.parse(clientInfo.getOverallContractStartDate())) >
	// 0) {
	// this.getLatestInfoResult(clientInfo, info);
	// } else {
	// this.getClientInfoResult(clientInfo);
	// }
	// } else if (info.getObligationStartDate() == null
	// && clientInfo.getOverallContractStartDate() != null) {
	// this.getClientInfoResult(clientInfo);
	// } else if (info.getObligationStartDate() != null
	// && clientInfo.getOverallContractStartDate() == null) {
	// this.getLatestInfoResult(clientInfo, info);
	// } else {
	// this.getLatestInfoResult(clientInfo, info);
	// }
	// }
	// } else if (info.getObligationType().equalsIgnoreCase("P")) {
	// if (info.getActiveEntitlementIndicator() != null
	// && info.getActiveEntitlementIndicator().equalsIgnoreCase("TRUE")
	// && clientInfo.getActive() != null
	// && !clientInfo.getActive().equalsIgnoreCase("TRUE")) {
	// this.getLatestInfoResult(clientInfo, info);
	// } else if (info.getActiveEntitlementIndicator() != null
	// && !info.getActiveEntitlementIndicator().equalsIgnoreCase("TRUE")
	// && clientInfo.getActive() != null
	// && clientInfo.getActive().equalsIgnoreCase("TRUE")) {
	// this.getClientInfoResult(clientInfo);
	// } else if (info.getActiveEntitlementIndicator() != null
	// && !info.getActiveEntitlementIndicator().equalsIgnoreCase("TRUE")
	// && clientInfo.getActive() != null
	// && !clientInfo.getActive().equalsIgnoreCase("TRUE")) {
	// if (info.getOfferCode().equalsIgnoreCase(clientInfo.getOfferCode())) {
	// if (info.getObligationStartDate() != null
	// && clientInfo.getOverallContractStartDate() != null) {
	// if (formatter.parse(info.getObligationStartDate()).compareTo(
	// formatter.parse(clientInfo.getOverallContractStartDate())) > 0) {
	// this.getLatestInfoResult(clientInfo, info);
	// } else {
	// this.getClientInfoResult(clientInfo);
	// }
	// } else if (info.getObligationStartDate() == null
	// && clientInfo.getOverallContractStartDate() != null) {
	// this.getClientInfoResult(clientInfo);
	// } else if (info.getObligationStartDate() != null
	// && clientInfo.getOverallContractStartDate() == null) {
	// this.getLatestInfoResult(clientInfo, info);
	// } else {
	// this.getLatestInfoResult(clientInfo, info);
	// }
	// } else {
	// if (carePackObligationInfos.isEmpty() || carePackObligationInfos.size() <
	// 1) {
	// carePackObligationInfos = this.getCarePacks(clientInfo, info,
	// carePackObligationInfos);
	// } else {
	// CarePackObligationInfo coi = new CarePackObligationInfo();
	// for (CarePackObligationInfo cois : carePackObligationInfos) {
	// if (!cois.getOfferCode().equalsIgnoreCase(cois.getOfferCode())) {
	// coi = this.getCarePack(cois);
	// }
	// }
	// carePackObligationInfos.add(coi);
	// clientInfo.setCarePackObligationInfo(carePackObligationInfos);
	// }
	// }
	// }
	// } else if (info.getObligationType().equalsIgnoreCase("W")) {
	// if (info.getActiveEntitlementIndicator() != null
	// && info.getActiveEntitlementIndicator().equalsIgnoreCase("TRUE")) {
	// this.getLatestInfoResult(clientInfo, info);
	// } else if (clientInfo.getActiveEntitlementIndicator() != null
	// && clientInfo.getActiveEntitlementIndicator().equalsIgnoreCase("TRUE")) {
	// clientInfo = this.getClientInfoResult(clientInfo);
	// } else {
	// if (info.getObligationStartDate() != null
	// && clientInfo.getOverallContractStartDate() != null) {
	// if (formatter.parse(info.getObligationStartDate())
	// .compareTo(formatter.parse(clientInfo.getOverallContractStartDate())) >
	// 0) {
	// this.getLatestInfoResult(clientInfo, info);
	// } else {
	// this.getClientInfoResult(clientInfo);
	// }
	// } else if (info.getObligationStartDate() == null
	// && clientInfo.getOverallContractStartDate() != null) {
	// this.getClientInfoResult(clientInfo);
	// } else if (info.getObligationStartDate() != null
	// && clientInfo.getOverallContractStartDate() == null) {
	// this.getLatestInfoResult(clientInfo, info);
	// } else {
	// this.getLatestInfoResult(clientInfo, info);
	// }
	// }
	// }
	// }
	// }
	// }
	// obligationClientInfoList.add(clientInfo);
	// }
	// return obligationClientInfoList;
	// }
	//
	public  ObligationInfo isPrinterEntitle(String productID, String serialNumber) throws Exception {
		ObligationInfoService obligationInfoService = new ObligationInfoServiceImpl();
		List<ObligationInfo> obligationInfos = obligationInfoService
				.retrieveActiveOrLatestServiceObligationByProductIdentifier(serialNumber, productID, null,
						null);
		if (obligationInfos!=null&&obligationInfos.size()>0)
		return obligationInfos.get(0);

		return new ObligationInfo();
	}
}
